﻿/*
   Represent Rectangles
   Created by Randall Maas, Tuesday Feb 3 2009
   Portions from pinvoke.net
   Copyright (c) 2009, Randall Maas
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

   Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

   Neither the name of Blackwood Designs, LLC nor the names of its contributors
   may be used to endorse or promote products derived from this software without
   specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   THE POSSIBILITY OF SUCH DAMAGE.
*/

using System ;
using System . Runtime . InteropServices;
using System . Drawing;

/// <summary>
/// A structure used to bridge with Win32 
/// </summary>
/// <seealso cref="http://pinvoke.net/default.aspx/Structures.RECT" />
/// <seealso cref="http://msdn.microsoft.com/en-us/library/dd162897%28VS.85%29.aspx" /?
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct RECT
{
   /// <summary>
   /// The x coordinate of the left side
   /// </summary>
   internal int Left;

   /// <summary>
   /// The y coordinate of the upper (top) side
   /// </summary>
   internal int Top;

   /// <summary>
   /// The x coordinate of the right side
   /// </summary>
   internal int Right;

   /// <summary>
   /// The y coordinate of the lower (bottom) side
   /// </summary>
   internal int Bottom;

   /// <summary>
   /// Constructs a rectangle given an origin and size
   /// </summary>
   /// <param name="location">Origin of upper left corner</param>
   /// <param name="size">Size</param>
   public RECT(System.Drawing.Point location, System.Drawing.Size size)
   {
      Left   = location.X;
      Top    = location.Y;
      Right  = location.X + size.Width;
      Bottom = location.Y + size.Height;
   }


   /// <summary>
   /// The height of the rectangle
   /// </summary>
   public int  Height { get { return Bottom - Top; } }

   /// <summary>
   /// The width of the rectangle
   /// </summary>
   public int  Width  { get { return Right - Left; } }

   /// <summary>
   /// The size (height and width) of the rectangle
   /// </summary>
   public Size Size   { get { return new Size(Width, Height); } }

   /// <summary>
   /// The upper left corner of the rectangle
   /// </summary>
   public Point Location { get { return new Point(Left, Top); } }


   #region Conversion
   /// <summary>
   /// Converts a RECT to a Rectangle
   /// </summary>
   /// <param name="rect"></param>
   /// <returns>Rectangle</returns>
   public static implicit operator Rectangle(RECT rect)
   {
      return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
   }

   /// <summary>
   /// Converts a RECT to a RectangleF
   /// </summary>
   /// <param name="rect"></param>
   /// <returns>RectangleF</returns>
   public static implicit operator RectangleF(RECT rect)
   {
      return RectangleF.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
   }

   /// <summary>
   /// Converts a Rectangle to a RECT
   /// </summary>
   /// <param name="rect"></param>
   /// <returns>RECT</returns>
   public static implicit operator RECT(Rectangle rect)
   {
      RECT R = new RECT();
      R . Left   = rect . Left;
      R . Top    = rect . Top;
      R . Bottom = rect . Bottom;
      R . Right  = rect . Right ;
      return R;
   }
   #endregion

   /// <summary>
   /// The 
   /// </summary>
   /// <returns>A hash value</returns>
   public override int GetHashCode()
   {
      return Left ^ ((Top << 13) | (Top >> 0x13))
                  ^ ((Width << 0x1a) | (Width >> 6))
                  ^ ((Height << 7) | (Height >> 0x19));
   }

   /// <summary>
   /// Compares this rectangle with the passed object
   /// </summary>
   /// <param name="B"></param>
   /// <returns>true if this rectangle is rectangle is equal to passed object, false otherwise</returns>
   public override bool Equals(object B)
   {
      if (!(B is RECT))
        return false;
      RECT C = (RECT) B;
      return Left == C . Left && Right == C . Right && Top == C . Top && Bottom == C . Bottom;
   }

}
